home *** CD-ROM | disk | FTP | other *** search
/ Lattice ISP Synario Start… & ISP Encyclopedia 1997 / LATTICE Synario.iso / ispcode / source / icode5c.c < prev    next >
Encoding:
Text File  |  1997-06-24  |  36.4 KB  |  817 lines

  1. /****************************************************************************
  2. *                            ispCODE5C.c                                    *
  3. *                   ispCODE for ispLSI 2000V Devices                        *
  4. *              Lattice Semiconductor Corp. Copyright 1996,1997.             *
  5. *                                                                           *
  6. * ISP(tm) daisy chain turbo programming is supported by ispCODE.            *
  7. *                                                                           *
  8. * The function of ispCODE is to step the IEEE 1149.1 TAP state machine      *
  9. * in the ispLSI devices for programming and verification. The input file    *
  10. * for ispCODE is ispSTREAM file.                                            *
  11. *                                                                           *
  12. * The ispSTREAM file is created by the command line program dld2isp.exe     *
  13. * and the ISP Daisy Chain Download program version 1.3 or higher.           *
  14. *                                                                           *
  15. * This version of ispCODE is the much simplified version of ispCODE V3.xx   *
  16. * by removing the PES checking, the post BULK ERASE verification and the    *
  17. * simultaneous shifting data in and out. The programming time is thus a bit *
  18. * longer than V3.xx due to the additional time needed to shift data in and  *
  19. * out separately. It is a very little price to pay for a 50% reduction in   *
  20. * code size which is especially critical for embedded controller programming*
  21. * where resources is extremely limited.                                     *
  22. *                                                                           *
  23. * The file size of Super FULL ispSTREAM is about 30% less than the FULL     *
  24. * ispSTREAM. The saving comes from replacing long chain of 0xFFs with       *
  25. * the number of consecutive 0xFF bytes. For example:                        *
  26. *           0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x03,0xC3                *
  27. *                                                                           *
  28. * The Super FULL ispSTREAM file is created by the command line program      *
  29. * dld2isp.exe v4.03 with the option sf selected. For example: type          *
  30. *                  dld2isp  design.dld sf                                   *
  31. *                                                                           *
  32. * All ispLSI 2000LV family of devices support the IEEE 1149.1 32-bit        *
  33. * USERCODE. The USERCODE data must be appended into the JEDEC file if it    *
  34. * is to be programmed into the device. The UES editor on the ISP Daisy      *
  35. * Chain Download should be used to add or modify the USERCODE data.         *
  36. * It is important to note that USERCODE is only 32 bits long. The extra     *
  37. * bits will still be written into the JEDEC file but will be discarded      *
  38. * during USERCODE programming if more than 32 bits of data is entered       *
  39. * on the UES editor.                                                        *
  40. *                                                                           *
  41. * Programming and verification always include all Array Cells and the       *
  42. * entire USERCODE. The USERCODE is programmed to be FFFFFFFF in hex by      *
  43. * default.                                                                  *
  44. *                                                                           *
  45. * The procedure of reading USERCODE is as follows:                          *
  46. * 1. Raise TMS to VIH and pulse TCK 6 times to step to Test-Logic Reset     *
  47. *    state.                                                                    *
  48. * 2. TMS to VIL, pulse TCK 1 time.                                          *
  49. * 3. TMS to VIH, pulse TCK 2 times.                                         *
  50. * 4. TMS to VIL, pulse TCK 2 times to step to Shift-IR state.               *
  51. * 5. TMS stay at VIL, shift in the VERIFY_USERCODE instruction 10111        *
  52. *    into the IR via TDI and pulse TCK. The instruction is shifted in       *
  53. *    from right to left, i.e. 1, 1, 1, 0 and 1. Repeat the instruction      *
  54. *    if there is more than one ispLSI device in the chain. Raise TMS to     *
  55. *    VIH while shifting in the last bit.                                    *
  56. * 6. Keep TMS at VIH, pulse TCK 2 times to step to Select-DR-Scan state.    *
  57. * 7. TMS to VIL, pulse TCK 2 times to step to Shift-DR state.               *
  58. * 8. Keep TMS at VIL, pulse TCK 32 times to shift out the 32 bits           *
  59. *    USERCODE on TDO. Pulse TCK 32 times more if more than one device       *
  60. *    in the chain. Raise TMS to VIH while shifting out the last bit.        *
  61. *                                                                           *
  62. * 9. Keep TMS at VIH and pulse TCK 6 times to go back to Test-Logic         *
  63. *    Reset state to end the procedure.                                      *
  64. *                                                                           *
  65. * Revision history:                                                         *
  66. *   4.0   Howard Tang   05/16/96 Convert from V3.xx to support ISP(tm)      *
  67. *                                programming using the IEEE 1149.1 TAP      *
  68. *                                for ispLSI 2000LV family of devices.       *
  69. *                                ispLSI 3000 family of devices are also     *
  70. *                                supported if they are on bscan             *
  71. *                                daisy chain configuration.                 *
  72. *                                Simplify the code of ispstream_pump        *
  73. *                                for easier reading and use.                *
  74. *   5C.000 Howard Tang  11/01/96 Simplify codes.                            *
  75. *   5C.001 Howard Tang  01/17/97 Extend support to GDX devices.             *
  76. *                                                                           *
  77. *****************************************************************************/
  78. #include <stdio.h>
  79. #include <dos.h>
  80. #include <stdlib.h>
  81. #include <string.h>
  82. #include "lattice.h"
  83. #include "istream.hex"
  84.  
  85. /*Global variables */
  86. static short int      bit=0;       /*the current bit read from ispSTREAM*/
  87. static unsigned char curch;        /*the current data from ispSTREAM*/
  88. unsigned char *fp;                 /*the pointer to the ispSTREAM*/
  89. static short int inputport=inport1,       /*port address for the input port*/
  90.                  outputport=outport1;      /*port address for the output port*/
  91. static short int isp_pins=NUL;    /*3.02 holds the value of parallel port*/
  92.                                  /*     intialized to drive all pins to LOW*/
  93. static char     state;           /*4.0  Keep track of the state of the TAP
  94.                                         state machine.*/
  95.  
  96. /*prototypes*/
  97. void            pulse_width(unsigned short int milliseconds);
  98. void            execute(void);
  99. void            move_to_id_state(void);
  100. short int       ispstream_pump(short int operation, short int *end);
  101. void            error_handler(short int rcode, char *message);
  102. unsigned char   GetByte(void);
  103. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  104.                          short int *ProgramPulse, short int *RowLength, 
  105.                          unsigned short int *DataSize, 
  106.                          unsigned short int *IDStreamLength);
  107. char ispRead(unsigned short int DataSize, unsigned char *OutData);
  108. void ReadispSTREAMDataSize(unsigned short int  *DataSize);
  109. void ReadispSTREAMData(unsigned short int *DataSize, unsigned char *InData,
  110.                        char SF);
  111. char ispInstruction(char SF,char Send);
  112. void ispData( unsigned char *InData, unsigned short int DataSize);
  113. void program_enable(short int chips);
  114. void device_enable(short int chips);
  115.  
  116. /***************************************************************************
  117.    Function: isp_setpin(byte pins, byte value)
  118.  
  119.    Purpose:
  120.    To apply the specified value to the pins indicated. This routine will
  121.    likely be modified for specific systems. As an example, this code
  122.    is for the PC, as described below.
  123.  
  124.    This routine uses the IBM-PC standard Parallel port, along with the
  125.    schematic shown in Lattice documentation, to apply the signals to the
  126.    programming loop. 
  127.  
  128.    PC Parallel port pin    Signal name
  129.    --------------------    -----------
  130.          2                   out_SDI
  131.          3                   out_SCLK
  132.          4                   out_MODE
  133.          5                   out_ISP
  134.          6                   out_RESET
  135.          7                   DO5
  136.          8                   out_SENSE_CABLE_OUT    
  137.          9                   DO7
  138.          10                  in_SDO
  139.          12                  in_CABLE_SENSE_IN
  140.          15                  in_VCC_OK 
  141.          20                  GND
  142.  
  143.    Parameters:
  144.          - pins, which is actually a set of bit flags (defined in lattice.h) 
  145.            that correspond to the bits of the data port. Each of the I/O port 
  146.            bits that drives an isp programming pin is assigned a flag 
  147.            (through a #define) corresponding to the signal it drives. To 
  148.            change the value of more than one pin at once, the flags are added 
  149.            together, much like file access flags are.
  150.  
  151.            The bit flags are only set if the pin is to be changed. Bits that 
  152.            do not have their flags set do not have their levels changed. The 
  153.            state of the port is always manintained in the static global 
  154.            variable isp_pins, so that each pin can be addressed individually 
  155.            without disturbing the others.
  156.  
  157.          - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
  158.            values are valid. Any non-zero number sets the pin(s) high.
  159.  
  160.    Returns: nothing.
  161.  
  162.  
  163. **************************************************************************/
  164. void isp_setpin(unsigned char pins, unsigned char value)
  165. {
  166.   /* isp_pins is a Global value that keeps track of the current state
  167.      of the pins  */
  168.  
  169.   if( value ) /* set flagged pins HIGH */
  170.       isp_pins = pins | isp_pins;
  171.   else        /* set flagged pins LOW */
  172.       isp_pins = ~pins & isp_pins;
  173.  
  174.   /* value is put on Parallel port pins */
  175.   outp(outputport, isp_pins);
  176.  
  177. } /* isp_setpin() */
  178.  
  179.  
  180. /***************************************************************************
  181.    Function: isp_SDO()
  182.  
  183.    Purpose:
  184.    To get the value of the SDO pin from the input port.
  185.  
  186.    This routine is specific to the PC parallel port setup, but can easily
  187.    be changed to address each user's hardware.
  188.  
  189.    Parameters: none
  190.  
  191.    Returns: The value of SDO, as a byte, with a value of either 0 or 1.
  192.  
  193.    Notes:
  194.    - This routine uses the I/O port addresses contained in the global
  195.      variable inputport, declared in the lattice.h file. 
  196.  
  197. ****************************************************************************/
  198. unsigned char isp_SDO(void)
  199. {
  200.  /* MUST return either 0x00 or 0x01 */
  201.   return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
  202.  
  203. } /* isp_SDO() */
  204.  
  205. /*************************************************************
  206. *                                                            *
  207. *                         PULSE_WIDTH                        *
  208. * This procedure produce accurate timing only on straight PC *
  209. * DOS. The timing is not guarantee if use on Windows DOS.    *
  210. * The delay() function is available only from BORLAND.       *
  211. *                                                            *
  212. * Users must devise their own timing procedures to ensure    *
  213. * the specified minimum delay is observed when using         *
  214. * different platform.                                        *
  215. *************************************************************/
  216.  
  217.  
  218. void            pulse_width(unsigned short int milliseconds)
  219. {
  220.                 delay(milliseconds);
  221. }
  222.  
  223.  
  224.  
  225. /*************************************************************
  226. *                                                            *
  227. *                      GETBYTE                               *
  228. * This procedure reads a byte from the ispSTREAM.            *
  229. *************************************************************/
  230. unsigned char GetByte()
  231. {
  232.  return (*fp++);
  233. }
  234.  
  235.  
  236. /*************************************************************
  237. *                                                            *
  238. *                      SCLOCK                                *
  239. * This procedure apply a clock to TCK.                       *
  240. *************************************************************/
  241. void sclock(void)
  242. {
  243.  isp_setpin(out_SCLK,HIGH);
  244.  isp_setpin(out_SCLK,LOW);
  245. }
  246.  
  247. /*************************************************************
  248. *                                                            *
  249. *                       SHIFT/EXECUTE                        *
  250. * This procedure walk all devices in the daisy chain from a  *
  251. * given state to the next desirable state.                   * 
  252. *                                                            *
  253. *If at Idle state when enter then move to Shift-IR state.    *
  254. *If at Shift-IR state when enter then move to Shift-DR state.*
  255. *If at Shift-DR state when enter then move to Shift-IR state.*
  256. *If at Shift-IR state and state is set to time_state when    *
  257. *enter then move to Idle state.                              *
  258. *************************************************************/
  259. void execute()
  260. {
  261.  short int i,count;
  262.      if (state==time_state) 
  263.         {count = 1;   /*move from shift-IR to Idle state to start timing*/ 
  264.          state = idle_state;
  265.         }
  266.      else if (state==shift_state) 
  267.              {count = 2;  /*move from shift-IR to shift-DR*/
  268.               state = execute_state;
  269.              } 
  270.      else if (state==idle_state)
  271.              {count = 2;  /*move from Idle to shift-IR state*/
  272.               state = shift_state;
  273.              }
  274.      else if (state==execute_state)
  275.              {count = 3;  /*move from shift-DR to shift-IR*/
  276.               state = shift_state;
  277.              }
  278.      else count = 0;
  279.      isp_setpin(out_SCLK,LOW);
  280.      isp_setpin(out_MODE,LOW);
  281.      isp_setpin(out_SDI,LOW);
  282.      for (i=0; i<count; i++)
  283.          {
  284.           isp_setpin(out_MODE,HIGH);
  285.           sclock();
  286.          }
  287.      isp_setpin(out_MODE,LOW);
  288.      sclock();
  289.      if (count > 1) sclock();
  290.        /* at Shift-DR or Shift-IR state*/
  291.  
  292. }
  293.  
  294.  
  295. /*************************************************************
  296. *                                                            *
  297. *                      MOVE TO ID STATE                      *
  298. * This procedure walk all devices in the daisy chain to the  *
  299. * Test-Logic-Reset state then Run-Test/Idle state.           *
  300. *                                                            *
  301. *************************************************************/
  302.  
  303. void move_to_id_state()
  304. {
  305. int i;
  306.        isp_setpin(out_SCLK,LOW);
  307.        isp_setpin(out_MODE+out_SDI,LOW);
  308.        pulse_width(2);
  309.        isp_setpin(out_MODE,HIGH);            
  310.        pulse_width(2);
  311.        isp_setpin(out_SCLK,HIGH);
  312.        pulse_width(2);
  313.        isp_setpin(out_SCLK,LOW);
  314.        for (i=0; i<6; i++) sclock();
  315.        isp_setpin(out_MODE,LOW);
  316.        pulse_width(2);
  317.        sclock();   /*device is in Idle state*/
  318.        state = idle_state;
  319. }
  320.  
  321. /*************************************************************
  322. *                                                            *
  323. *                      PROGRAM ENABLE                        *
  324. * perform the 3 read id instruction to get devices into      *
  325. * programming mode.                                          *
  326. *************************************************************/
  327.  
  328. void program_enable(short int chips)
  329. {
  330. short int i,j,loops;
  331.  
  332. for (loops=0; loops<3; loops++)
  333.     {
  334.      for (i=0; i<chips+1; i++)
  335.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  336.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  337.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  338.               sclock();
  339.              }     
  340.      for (i=0; i<3; i++) sclock();
  341.      isp_setpin(out_MODE,LOW);
  342.      sclock(); sclock(); /*devices at Shift-IR state*/
  343.      
  344.     }     
  345. }
  346.  
  347. /*************************************************************
  348. *                                                            *
  349. *                      DEVICE ENABLE                         *
  350. * perform the read id instruction to get devices into        *
  351. * functional mode.                                           *
  352. *************************************************************/
  353.  
  354. void device_enable(short int chips)
  355. {
  356. short int i,j;
  357.  
  358. /*devices come in at Shift-IR state*/
  359.      for (i=0; i<chips+1; i++)
  360.          for (j=0; j<5; j++)  /*send the instruction into TDI*/
  361.              {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH);  /*last bit*/ 
  362.               isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
  363.               sclock();
  364.              }     
  365.      sclock();                /*devices at Update-IR state*/
  366.      isp_setpin(out_MODE,LOW);
  367.      for (i=0; i<20; i++) sclock();   /*go and loop on Run-Test/Idle for 10uS*/
  368.      isp_setpin(out_MODE,HIGH);
  369.      for (i=0; i<3; i++) sclock();   /*devices at Test-Logic-Reset and active*/
  370. }     
  371.  
  372. /**********************************************************************
  373. *                                                                     *
  374. *                     READ_ISPSTREAM_HEADER                           *
  375. * Extract the header from the ispSTREAM file.                         *
  376. * Return                                                              *
  377. *     ChainLength--------number of ispLSI devices in the              *
  378. *                        given daisy  chain.                          *
  379. *     ErasePulse---------pulse width in mS for device                 *
  380. *                        bulk erase.                                  *
  381. *     ProgramPulse-------pulse width in mS for device                 *
  382. *                        row by row programming.                      *
  383. *     RowLength----------the number of rows of data +UES              *
  384. *     DataSize-----------the largest size of each row of data.        *
  385. *     BEVend-------------the end of Bulk Erase verify.                *
  386. ***********************************************************************/
  387. void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse, 
  388.                          short int *ProgramPulse, short int *RowLength,
  389.                          unsigned short int *DataSize,
  390.                          unsigned short int *BEVend)
  391. {
  392.    
  393.    *ChainLength = GetByte();              
  394.    *ErasePulse = GetByte() * 0x100;
  395.    *ErasePulse += GetByte();
  396.    *ProgramPulse = GetByte(); 
  397.    *RowLength = GetByte() * 0x100;
  398.    *RowLength += GetByte();
  399.    *DataSize = GetByte() * 0x100;
  400.    *DataSize += GetByte();   
  401.    *BEVend = GetByte() * 0x100;
  402.    *BEVend += GetByte();
  403.    /*End of the header of the ispSTREAM file.*/   
  404.    
  405. }
  406.  
  407. /*********************************************************************
  408. *                                                                    *
  409. *                     READ_ISPSTREAM_DATA_SIZE                       *
  410. * Extract the data size of the current row from the ispSTREAM file.  *
  411. * Return                                                             *
  412. *     DataSize-----------The data bit length of the current row.     *
  413. **********************************************************************/
  414. void ReadispSTREAMDataSize(unsigned short int  *DataSize)
  415. {
  416.  short int index;
  417.  unsigned short int temp;
  418.  unsigned char xch;
  419.  
  420.  xch=0;
  421.  temp = 0;
  422.  for (index=0; index<16; index++)
  423.      {--bit;
  424.       if (bit<0) 
  425.          {
  426.           curch = GetByte();
  427.           bit=7;
  428.          }
  429.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  430.       if (index%8==7) {temp = temp * 0x100 + xch; xch=0;}
  431.      }  
  432.    *DataSize = temp;   
  433. }
  434.  
  435. /*****************************************************************
  436. *                                                                *
  437. *                     READ_ISPSTREAM_DATA                        *
  438. * Extract the data from the ispSTREAM file.                      *
  439. *     SF-----------------Super FULL ispSTREAM file if true.      *
  440. * Return                                                         *
  441. *     DataSize-----------The number of data bits  fetched.       *
  442. *     InData-------------The data stream from ispSTREAM file     *
  443. ******************************************************************/
  444. void ReadispSTREAMData(unsigned short int  *DataSize, unsigned char *InData,
  445.                        char SF)
  446. {
  447.  unsigned short int index,size;
  448.  short int j;
  449.  unsigned char xch;
  450.  short int FFcount=0;
  451.  
  452.  ReadispSTREAMDataSize(&size);
  453.  if (size > 0)         /*5c.001 retain the old size if the current row is NULL*/
  454.     *DataSize = size; 
  455.  j=0;
  456.  xch=0;
  457.  for (index=0; index<size; index++)
  458.      {--bit;
  459.       if (bit<0) 
  460.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  461.              { curch = GetByte(); 
  462.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  463.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  464.              }
  465.           else FFcount--; /*Use up the 0xFF chain first*/
  466.           bit=7;
  467.          }
  468.       if ((curch >> bit) & 0x01)  xch |= 0x80 >> index%8;                
  469.       if (index%8==7) {InData[j++] = xch; xch=0;}
  470.      }  
  471.  if (size > 0) InData[j] = xch;   /*save the last byte of the current row*//*5c.001*/
  472. }
  473.  
  474. /*****************************************************************
  475. *                                                                *
  476. *                     ispInstruction                             *
  477. * Extract the instruction from the ispSTREAM file and clock into *
  478. * the devices or throw away.                                     *
  479. *     SF-----------------Super FULL ispSTREAM file if true.      *
  480. *     Send---------------Send data to devices if true.           *
  481. * Return                                                         *
  482. *     NONE                                                       *
  483. ******************************************************************/
  484. char ispInstruction(char SF, char Send)
  485. {
  486.  short int index;
  487.  short int i;
  488.  unsigned short int size;
  489.  short int FFcount=0;
  490.  
  491.  ReadispSTREAMDataSize(&size);
  492.  for (index=0; index<size; index++)
  493.      {--bit;
  494.       if (bit<0) 
  495.          {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
  496.              { curch = GetByte(); 
  497.                if ((SF)&&(curch==0xFF)) /*Super FULL ispSTREAM file support*/
  498.                FFcount = GetByte();     /*The number of 0xFF bytes*/
  499.              }
  500.           else FFcount--; /*Use up the 0xFF chain first*/
  501.           bit=7;
  502.          }
  503.       if (Send) /*send the data to the devices*/
  504.          {isp_setpin(out_SDI,(curch >> bit) & 0x01);
  505.           if (index==size-1) isp_setpin(out_MODE,HIGH);
  506.           sclock();  /*clock the data into the command registers */
  507.          }
  508.      }
  509.  if ((Send)&&(size > 0)) 
  510.     {execute();  /*execute the instruction if sent*/
  511.      return (1); /*signify data or instruction has actually sent*/
  512.     }
  513.  else return (0); /*no data or instruction send to the devices*/
  514. }
  515.  
  516. /**********************************************************************
  517. *                                                                     *
  518. *                     ispData                                         *
  519. * Send the data stream to devices.                                    *
  520. *    InData-----------The data stream to be sent to devices.          *
  521. *    DataSize---------The length of the data stream.                  *
  522. ***********************************************************************/
  523. void ispData(unsigned char *InData, unsigned short int DataSize)
  524. {
  525.  unsigned short int index;
  526.  short int j;
  527.  unsigned char curch;
  528.  
  529.  j=0;
  530.  for (index = 0; index <DataSize; index++) { 
  531.       if (index%8==0) curch = InData[j++];
  532.       isp_setpin(out_SDI, (((curch << index%8) & 0x80) ? 0x01 : 0x00)); 
  533.       if (index==DataSize-1) isp_setpin(out_MODE,HIGH);
  534.       sclock();  /*clock data into the data shift registers */
  535.       }
  536.  if (DataSize > 0) execute();   /*step to shift state*//*5c.001*/ 
  537. }
  538.  
  539. /**********************************************************************
  540. *                                                                     *
  541. *                     ispRead                                         *
  542. * Read the data stream from devices and verify.                       *
  543. *    DataSize---------The length of the data stream.                  *
  544. *    OutData----------The data stream to be compare with those read   *
  545. *                     from devices.                                   *
  546. ***********************************************************************/
  547. char ispRead(unsigned short int DataSize, unsigned char *OutData)
  548. {
  549.  unsigned short int index,error;
  550.  unsigned char xch,cur_bit;
  551.  short int j;
  552.  
  553.  j=0;
  554.  error=0;
  555.  xch=0;
  556.  for (index = 0; index <DataSize; index++) { 
  557.       if (index%8==0) xch = OutData[j++];
  558.       cur_bit=isp_SDO(); 
  559.       if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00)) error++;  
  560.       if (index==DataSize-1) isp_setpin(out_MODE,HIGH);
  561.       sclock();  /*clock data out from the data shift registers */
  562.       }
  563.  execute();   /*step to shift state*/ 
  564.  if (error > 0) return 1;      /*Flag failure occur*/
  565.  else return (OK);
  566. }
  567.  
  568. /*************************************************************
  569. *                                                            *
  570. *                     ISPSTREAM_PUMP                         *
  571. *                                                            *
  572. *************************************************************/
  573.  
  574. short int   ispstream_pump(short int operation, short int *end)
  575. {
  576.    short int       row;
  577.    char            SF;                    /*ispSTREAM file types identifier*/
  578.    char            send;                  /*send data to devices if true*/
  579.    char            ready;                 /*5c.001 ready to verify data*/
  580.    unsigned char   FileType;
  581.    short int       last_row,
  582.                    erase_pulse,
  583.                    program_pulse,
  584.                    devices_in_chain;
  585.    unsigned short int    maxi_data,
  586.                          data_length,
  587.                             be_row;
  588.    short int       rcode,condition;
  589.    unsigned char   *buf;
  590.  
  591.    row =0;
  592.    bit = 0;
  593.    /*Start reading the header of the ispSTREAM file*/
  594.    fp = ispstream;
  595.    FileType = GetByte();
  596.    if (FileType == 0xF0) {SF=false;}          /*Check for correct file type*/
  597.    else if (FileType == 0x0b ) {SF=true;}     /*Super FULL ispSTREAM file found*/ 
  598.    else {
  599.         return FILE_NOT_JEDEC;
  600.        }
  601.    ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
  602.                            &last_row, &maxi_data, &be_row);
  603.  
  604.    rcode = OK;                                /*Success by default.*/
  605.    if ((operation==verify)||(operation==verify_ues))    /*verify only*/
  606.       {erase_pulse=0;                       /*void the erase instruction*/ 
  607.        program_pulse=0;                     /*void the program instruction*/
  608.       }
  609.    
  610.    /*Allocate memory to store one row of data from the ispSTREAM file.*/
  611.    buf = buffer;
  612.  
  613.    /*set the initial condition of the parallel port*/
  614.    /*     All the port_pins defined on lattice.h will be controlled by
  615.           ispstream_pump(). The rest can be initialized here either to
  616.           HIGH or LOW and won't be altered by isptream_pump*/
  617.             
  618.    isp_pins = NUL;          /* intialize to drive all port pins LOW*/
  619.    isp_setpin(out_ISP, LOW);/*  drive ispEN pin low to enable the 
  620.                                    ispJTAG controlling pins:
  621.                                    TCK,TMS,TDI and TDO.*/ 
  622.    move_to_id_state();      /* Go to Reset then Run-Test/Idle state*/
  623.    isp_setpin(out_MODE,HIGH); 
  624.    sclock();
  625.    isp_setpin(out_MODE,LOW);
  626.    sclock(); sclock();
  627.    state=execute_state;     /* At shift-DR state*/
  628.    isp_setpin(out_SDI,HIGH);
  629.    ReadispSTREAMData(&data_length,buf,SF);   /*fetch ID stream from ispSTREAM*/
  630.    rcode = ispRead(data_length,buf);            /*verify the ID stream*/    
  631.    if (rcode != OK)     
  632.       {
  633.        return UNKNOWN_CHIP;      
  634.       }
  635.    for (row=1; row<be_row; row++)   
  636.        {switch(row)
  637.          { case 8:program_enable(devices_in_chain);/*enable programming*/ 
  638.                   if (erase_pulse > 0)             /*erase the devices*/
  639.                     {
  640.                      state=time_state;
  641.                      ispInstruction(SF,true);
  642.                      sclock();                    /*start the erase timing*/
  643.                      pulse_width(erase_pulse);    /*erase pulse*/
  644.                      isp_setpin(out_MODE, HIGH);
  645.                      isp_setpin(out_SCLK,HIGH);
  646.                      pulse_width(1);              /*super voltage discharge*/
  647.                      isp_setpin(out_SCLK,LOW);
  648.                      sclock(); 
  649.                      isp_setpin(out_MODE,LOW);    
  650.                      sclock(); sclock();          /*devices in shift state*/
  651.                      state=shift_state;
  652.                     }
  653.                   else ispInstruction(SF,false); /*skipp BULK ERASE*/
  654.                  break;
  655.          default:if (((row-9)%12==3)||((row-9)%12==8)) /*skipp BULK ERASE verify*/
  656.                     ReadispSTREAMDataSize(&data_length);         
  657.                  else ispInstruction(SF,false);    
  658.                  break;}
  659.        }
  660.    /*start processing the rows in the ispSTREAM file*/
  661.    data_length = 0;
  662.    for (; row <= last_row; row++) {
  663.        *end = row;                               /* The row number where process ended.*/
  664.        if (row==last_row) condition = 8;         /* security programming*/
  665.        else condition = (row-9) % 12;
  666.        if ((operation==verify_ues)&&(row <= last_row-DATAROW)) send = false;
  667.        else send = true;
  668.        switch(condition){
  669.            case 0:                              /*address shift*/
  670.            case 1:ispInstruction(SF,send);      /*address data*/
  671.                   break;
  672.            case 2:                              /*data shift*/
  673.            case 7:ready=ispInstruction(SF,send);   /*5c.001 data shift*/
  674.                   break;
  675.            case 3:                              /*shift data in/out of devices*/
  676.            case 8:
  677.                   if ((data_length > 0)&&(ready))  /*5c.001 verify the data shifted in*/
  678.                      {state=idle_state;           /*loop back to Shift-DR*/
  679.                       rcode = ispRead(data_length,buf);   
  680.                       state=execute_state;          /*back to shift-DR state*/
  681.                       data_length=0;                /*5c.001 data verified*/
  682.                      }
  683.                   ReadispSTREAMData(&data_length,buf,SF); /*fetch data stream from ispSTREAM*/
  684.                   if (ready) ispData(buf,data_length);  /*send data into devices*/
  685.                   break;
  686.            case 4:
  687.            case 9:if (program_pulse > 0)        /*program and verify*/
  688.                      {
  689.                       state=time_state;
  690.                       if (ispInstruction(SF,true))     /*5c.001 program commands exist*/
  691.                          {sclock();                    /*start program timing*/
  692.                           pulse_width(program_pulse);
  693.                           execute();                   /*step to shift state*/
  694.                          }
  695.                       state=shift_state;               /*5c.001 at Shift-IR*/
  696.                      }
  697.                   else ispInstruction(SF,false);   /*skip programming*/
  698.                   break;
  699.            case 5:
  700.           case 10:state=time_state;
  701.                   if(ispInstruction(SF,send))         /*verify*/
  702.                     {sclock();                           /*start verify timing*/
  703.                      pulse_width(1);                     /*30uS min. verify time*/
  704.                      execute();                          /*step to shift state*/
  705.                     }
  706.                   state=shift_state;                     /*5c.001 at Shift-IR*/
  707.                   break;
  708.            case 6:
  709.           case 11:if (ispInstruction(SF,send))
  710.                   {   rcode = ispRead(data_length,buf);   /*verify the data stream*/
  711.                       data_length=0;                      /*don't verify again*/
  712.                   }
  713.                   break;
  714.           default:break;
  715.          }
  716.        if (rcode != OK) break;  
  717.        }                              
  718.            
  719.    device_enable(devices_in_chain);  /*activate the devices*/
  720.    isp_setpin(out_ISP,HIGH);  /*activate the ispLSI devices*/
  721.    if (rcode==OK) 
  722.       return (OK);
  723.    else  return VALIDATION_ERROR;      
  724.  
  725. }
  726.  
  727.  
  728. /*************************************************************
  729. *                                                            *
  730. *                         error_handler                      *
  731. *                                                            *
  732. *  rcode                  - error code                       *
  733. *                                                            *
  734. *                                                            *
  735. *  This procedure return the address of the message string   *
  736. *  for the corresponding error code.                         *
  737. *                                                            *
  738. *************************************************************/
  739.  
  740. void error_handler(short int rcode, char *message)
  741. {
  742.  
  743. char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
  744.                    {""},{""},
  745.                    {"No Device Found/Open Download Cable/Open Daisy Chain"},
  746.                    {"Can't Find the File"},{""},{"Not Enough PC Memory"},
  747.                    {"Verification Fail"},{""},{""},
  748.                    {""},
  749.                    {"The Chip Count in the Chain and the File Do Not Match"},
  750.                    {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
  751.                    {""}};
  752.  
  753.  strcpy(message, error_message[-rcode]);
  754.  
  755. /*************************************************************
  756. *                                                            *
  757. *                            MAIN                            *
  758. *                                                            *
  759. *************************************************************/
  760.  
  761. short int             main(int argc, char *argv[])
  762. {
  763.    short int       rcode = OK,
  764.                    end = 0;
  765.    char            str[300];
  766.    
  767.    short int operation=prog_verify;  /*3.05 Default to Program and Verify*/
  768.    
  769.    printf("\n                 Lattice Semiconductor Corp.\n");
  770.    printf("\n               ispCODE V5C.001 Copyright 1996,1997.\n");
  771.    printf("\n           ispSTREAM Driver for ispLSI 2000V Devices\n");
  772.    printf("\n  For Daisy Chain of All ISP Devices On JTAG TAP Controller\n\n");
  773.  
  774.    if ((argc < 1) || (argc > 2)) {
  775.       printf("\nUsage: sturbo [operation]\n");
  776.       printf("Example: sturbo pv\n");
  777.       printf("\n");
  778.       printf("operation            \"pv\" = program and verify\n");
  779.       printf("                     \"v\" = Verify only\n");
  780.       printf("                     \"uv\" = Verify UES only\n");
  781.       printf("                     Default to pv if operation is not entered.\n");                            
  782.       exit(1);
  783.    }
  784.  
  785.       if (rcode == OK){        /*start programming and verification*/
  786.                 
  787.           if(!strcmp(strlwr(argv[1]),"uv")){                  /*3.05 What to do? uv=ues verify only*/
  788.               operation=verify_ues;                                      /*for verify ues only =1*/  
  789.               printf("\nStart Verify UES of ispLSI devices.......\n");}  
  790.           else if(!strcmp(strlwr(argv[1]),"v")){               /*v = verify only*/
  791.               operation=verify;
  792.               printf("\nStart Verify.......\n");}
  793.           else {                                               /*pv = program and verify: Default*/
  794.                   operation=prog_verify;
  795.                   printf("\nStart Program and Verify.......\n");
  796.                }    
  797.         rcode = ispstream_pump(operation, &end);       /*3.05 add operation switch*/
  798.        }
  799.    if (rcode != OK) {
  800.       error_handler(rcode, str);
  801.       printf("\nFailed At Row %d in Program and Verify Due To %s\n", end, str);
  802.       printf("\n");
  803.       printf("+-------+\n");
  804.       printf("| FAIL! |\n");
  805.       printf("+-------+\n");
  806.       return (-rcode);
  807.    } else {
  808.       printf("\n");
  809.       printf("+=======+\n");
  810.       printf("| PASS! |\n");
  811.       printf("+=======+\n");
  812.    }
  813.  
  814.    return(0);
  815.